#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# cron: 30 22 * * *
# new Env("康师傅瓶盖每日统计")

import os
import re
import glob
import json
import logging
import requests
import subprocess
from collections import defaultdict
from datetime import datetime, timedelta

# 配置日志格式
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger("ScanCodeStats")

# ====================== 配置区域 ======================
LOG_DIR_PATTERN = "/ql/data/log/WXyuedu_康师傅*"  # 日志目录模式（支持通配符）
TIME_RANGE_HOURS = 24  # 分析最近多少小时的日志
DEBUG_MODE = False      # 设置为True启用详细调试日志
REPORT_FILE = "/ql/data/log/Message/PUSH_ksfpg.log"  # 报告保存路径

# 获取当前脚本所在目录
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
# =====================================================

# 在logger定义后设置调试模式
if DEBUG_MODE:
    logger.setLevel(logging.DEBUG)
    logger.debug("调试模式已启用")

def parse_scan_logs(log_content):
    """
    解析扫码日志内容并提取统计信息
    """
    # 初始化数据结构
    account_data = {}
    
    # 编译正则表达式
    account_start_pattern = re.compile(r'--------开始第\d+个账号--------')
    account_name_pattern = re.compile(r'\[INFO\]\s+===>\s+\[(.*?)\]开始运行')
    account_end_pattern = re.compile(r'✅️账号\[(.*?)\]运行完毕')
    
    # 增强的统计信息正则 - 修复废码提取问题
    # 匹配格式: "废码数量[2]" 或 "废码数量:[2]" 等变体
    valid_pattern = re.compile(r'有效扫码数量\s*[:：]?\s*\[(\d+)\]')
    waste_pattern = re.compile(r'废码数量\s*[:：]?\s*\[(\d+)\]')  # 修复废码匹配问题
    income_pattern = re.compile(r'🏆️?共获得\s*[:：]?\s*\[([\d.]+)\]元')
    cost_pattern = re.compile(r'💷?成本\s*[:：]?\s*\[([\d.]+)\]元')
    profit_pattern = re.compile(r'💵?收益\s*[:：]?\s*\[([\d.]+)\]元')
    
    # 状态变量
    current_account = None
    in_account_block = False
    in_summary_block = False
    current_block_data = None
    
    lines = log_content.split('\n')
    for line in lines:
        line = line.strip()
        if not line:
            continue
            
        # 检测账号块开始
        if account_start_pattern.match(line):
            in_account_block = True
            current_account = None
            in_summary_block = False
            current_block_data = None
            logger.debug(f"检测到账号块开始: {line}")
            continue
            
        if not in_account_block:
            continue
            
        # 提取账号名称
        if current_account is None:
            name_match = account_name_pattern.search(line)
            if name_match:
                current_account = name_match.group(1)
                current_block_data = {
                    'valid': 0,
                    'waste': 0,
                    'income': 0.0,
                    'cost': 0.0,
                    'profit': 0.0
                }
                logger.debug(f"检测到账号: {current_account}")
            continue
            
        # 检测账号运行结束
        if not in_summary_block:
            end_match = account_end_pattern.search(line)
            if end_match:
                account_name = end_match.group(1)
                if account_name != current_account:
                    logger.warning(f"账号名不一致: 当前'{current_account}', 汇总行'{account_name}'")
                in_summary_block = True
                logger.debug(f"检测到账号结束: {current_account}")
            continue
            
        # 提取统计信息 - 允许一行匹配多个字段
        if in_summary_block:
            matched = False
            
            # 有效扫码数量
            valid_match = valid_pattern.search(line)
            if valid_match:
                current_block_data['valid'] = int(valid_match.group(1))
                logger.debug(f"{current_account} 有效扫码: {current_block_data['valid']}")
                matched = True
                
            # 废码数量 - 修复提取问题
            waste_match = waste_pattern.search(line)
            if waste_match:
                current_block_data['waste'] = int(waste_match.group(1))
                logger.debug(f"{current_account} 废码: {current_block_data['waste']}")
                matched = True
                
            # 收益金额
            income_match = income_pattern.search(line)
            if income_match:
                current_block_data['income'] = float(income_match.group(1))
                logger.debug(f"{current_account} 收益: {current_block_data['income']}")
                matched = True
                
            # 成本金额
            cost_match = cost_pattern.search(line)
            if cost_match:
                current_block_data['cost'] = float(cost_match.group(1))
                logger.debug(f"{current_account} 成本: {current_block_data['cost']}")
                matched = True
                
            # 利润金额
            profit_match = profit_pattern.search(line)
            if profit_match:
                current_block_data['profit'] = float(profit_match.group(1))
                logger.debug(f"{current_account} 利润: {current_block_data['profit']}")
                matched = True
                
            # 检测账号块结束
            if line.startswith('--------') and '执行完毕--------' in line:
                # 保存当前账号数据
                if current_account in account_data:
                    # 如果账号已存在，累加数据
                    existing = account_data[current_account]
                    account_data[current_account] = {
                        'valid': existing['valid'] + current_block_data['valid'],
                        'waste': existing['waste'] + current_block_data['waste'],
                        'income': existing['income'] + current_block_data['income'],
                        'cost': existing['cost'] + current_block_data['cost'],
                        'profit': existing['profit'] + current_block_data['profit']
                    }
                    logger.debug(f"账号数据累加: {current_account}")
                else:
                    account_data[current_account] = current_block_data
                
                logger.info(f"账号统计: {current_account} - "
                           f"有效扫码: {current_block_data['valid']}, "
                           f"废码: {current_block_data['waste']}, "
                           f"收益: {current_block_data['income']}元, "
                           f"成本: {current_block_data['cost']}元, "
                           f"利润: {current_block_data['profit']}元")
                
                # 重置状态
                in_account_block = False
                in_summary_block = False
                current_account = None
                current_block_data = None
            elif matched:
                # 如果匹配到任何数据，跳过后续处理
                continue
    
    return account_data

def process_log_directories():
    """
    处理日志目录并解析所有匹配的日志文件
    返回合并后的账号统计数据
    """
    # 计算时间范围（最近N小时）
    time_threshold = datetime.now() - timedelta(hours=TIME_RANGE_HOURS)
    logger.info(f"分析时间范围: {time_threshold.strftime('%Y-%m-%d %H:%M:%S')} 至今")
    
    all_account_data = defaultdict(lambda: {
        'valid': 0,
        'waste': 0,
        'income': 0.0,
        'cost': 0.0,
        'profit': 0.0
    })
    
    processed_files = 0
    skipped_files = 0
    
    # 遍历匹配的日志目录
    for log_dir in glob.glob(LOG_DIR_PATTERN):
        if not os.path.isdir(log_dir):
            logger.warning(f"跳过非目录项: {log_dir}")
            continue
            
        logger.info(f"处理目录: {log_dir}")
        
        # 遍历目录中的日志文件
        for filename in os.listdir(log_dir):
            if not filename.endswith('.log'):
                continue
                
            file_path = os.path.join(log_dir, filename)
            
            # 检查文件修改时间
            try:
                file_mtime = datetime.fromtimestamp(os.path.getmtime(file_path))
                if file_mtime < time_threshold:
                    skipped_files += 1
                    if DEBUG_MODE:
                        logger.debug(f"跳过旧文件: {filename} ({file_mtime})")
                    continue
            except Exception as e:
                logger.error(f"文件时间检查失败: {file_path} - {str(e)}")
                continue
                
            # 处理日志文件
            try:
                logger.info(f"分析文件: {filename}")
                with open(file_path, 'r', encoding='utf-8') as f:
                    content = f.read()
                    file_account_data = parse_scan_logs(content)
                    
                    # 合并账号数据
                    for account, data in file_account_data.items():
                        all_account_data[account]['valid'] += data['valid']
                        all_account_data[account]['waste'] += data['waste']
                        all_account_data[account]['income'] += data['income']
                        all_account_data[account]['cost'] += data['cost']
                        all_account_data[account]['profit'] += data['profit']
                    
                    processed_files += 1
            except Exception as e:
                logger.error(f"文件解析失败: {file_path} - {str(e)}")
    
    logger.info(f"文件处理完成: 已处理 {processed_files} 个文件, 跳过 {skipped_files} 个")
    return dict(all_account_data)

def generate_report(account_data):
    """生成精简统计报告"""
    if not account_data:
        return "⚠️ 未找到有效的账号统计信息", {}
    
    # 计算总计
    totals = {
        'accounts': len(account_data),
        'valid': 0,
        'waste': 0,
        'income': 0.0,
        'cost': 0.0,
        'profit': 0.0,
        'success_rate': 0.0
    }
    
    for data in account_data.values():
        totals['valid'] += data['valid']
        totals['waste'] += data['waste']
        totals['income'] += data['income']
        totals['cost'] += data['cost']
        totals['profit'] += data['profit']
    
    # 计算总扫码成功率
    total_scans = totals['valid'] + totals['waste']
    if total_scans > 0:
        totals['success_rate'] = (totals['valid'] / total_scans) * 100
    
    # 构建报告 - 最前面显示全局汇总
    report_lines = [
        "📊 康师傅瓶盖扫码统计报告",
        "=" * 50,
        f"👥 总账号数: {totals['accounts']}个",
        f"✅ 总有效扫码: {totals['valid']}个",
        f"❌ 总废码量: {totals['waste']}个",
        f"📈 扫码成功率: {totals['success_rate']:.2f}%",
        f"💰 总收益: {totals['income']:.2f}元",
        f"💸 总成本: {totals['cost']:.2f}元",
        f"🏆 总利润: {totals['profit']:.2f}元",
        "=" * 50,
        "👤 账号详情:"
    ]
    
    # 添加每个账号的统计（一行一个账号）
    for account, data in account_data.items():
        # 计算账号扫码成功率
        account_total = data['valid'] + data['waste']
        success_rate = (data['valid'] / account_total) * 100 if account_total > 0 else 0
        
        profit_icon = "💰" if data['profit'] >= 0 else "💸"
        account_line = (
            f"👤 {account.ljust(12)}: "
            f"✅{str(data['valid']).ljust(3)} "
            f"❌{str(data['waste']).ljust(3)} "
            f"📈{success_rate:6.2f}% "
            f"💵{data['income']:6.2f} "
            f"{profit_icon}{data['profit']:7.2f}"
        )
        report_lines.append(account_line)
    
    # 添加分隔线
    report_lines.append("=" * 50)
    report_lines.append(f"📅 报告生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    
    return "\n".join(report_lines), totals

def push_plus_notify(title, content):
    """
    使用PUSH_PLUS推送通知
    """
    token = os.environ.get('PUSH_PLUS_TOKEN')
    if not token:
        logger.error("未找到PUSH_PLUS_TOKEN环境变量，无法发送通知")
        return False
    
    try:
        # PUSH_PLUS API地址
        url = "http://www.pushplus.plus/send"
        
        # 请求数据
        data = {
            "token": token,
            "title": title,
            "content": content,
            "template": "txt"
        }
        
        # 发送请求
        response = requests.post(url, json=data)
        result = response.json()
        
        if response.status_code == 200 and result.get("code") == 200:
            logger.info("PUSH_PLUS通知发送成功")
            return True
        else:
            logger.error(f"PUSH_PLUS通知发送失败: {result.get('msg', '未知错误')}")
            return False
    except Exception as e:
        logger.error(f"发送PUSH_PLUS通知时出错: {str(e)}")
        return False

def send_notification(title, content):
    """
    发送通知（优先使用PUSH_PLUS）
    """
    # 使用PUSH_PLUS发送通知
    if push_plus_notify(title, content):
        return True
    
    logger.warning("PUSH_PLUS通知发送失败，尝试使用其他通知方式")
    return False

def main():
    """主函数"""
    task_start = datetime.now()
    logger.info("开始康师傅瓶盖扫码统计任务")
    
    try:
        # 步骤1: 处理日志目录
        account_data = process_log_directories()
        
        # 步骤2: 生成报告
        report, totals = generate_report(account_data)
        
        # 步骤3: 输出报告
        logger.info("\n" + report)
        
        # 步骤4: 保存报告到文件
        os.makedirs(os.path.dirname(REPORT_FILE), exist_ok=True)
        with open(REPORT_FILE, 'w', encoding='utf-8') as f:
            f.write(report)
        logger.info(f"统计报告已保存至: {REPORT_FILE}")
        
        # 步骤5: 发送通知（包含所有账号详情）
        if account_data:
            # 创建通知标题
            title = f"康师傅瓶盖扫码统计 ({totals['accounts']}账号)"
            
            # 创建通知内容（包含全局汇总和所有账号详情）
            total_scans = totals['valid'] + totals['waste']
            success_rate = (totals['valid'] / total_scans) * 100 if total_scans > 0 else 0
            
            notify_content = [
                f"🔄 统计时段: 最近{TIME_RANGE_HOURS}小时",
                f"👥 总账号数: {totals['accounts']}个",
                f"✅ 有效扫码: {totals['valid']}个",
                f"❌ 废码数量: {totals['waste']}个",
                f"📈 扫码成功率: {success_rate:.2f}%",
                f"💰 总收益: {totals['income']:.2f}元",
                f"💸 总成本: {totals['cost']:.2f}元",
                f"🏆 总利润: {totals['profit']:.2f}元",
                "",
                "📋 账号详情:"
            ]
            
            # 添加所有账号详情（精简格式）
            for account, data in account_data.items():
                account_total = data['valid'] + data['waste']
                acc_success_rate = (data['valid'] / account_total) * 100 if account_total > 0 else 0
                profit_icon = "↑" if data['profit'] >= 0 else "↓"
                
                # 精简账号名称（保留前4个字符）
                short_name = account[:4] + ".." if len(account) > 6 else account
                
                account_info = (
                    f"👤 {short_name.ljust(6)}: "
                    f"✅{data['valid']} "
                    f"❌{data['waste']} "
                    f"📈{acc_success_rate:.1f}% "
                    f"💵{data['income']:.2f} "
                    f"💸{data['cost']:.2f} "
                    f"{profit_icon}{data['profit']:.2f}"
                )
                notify_content.append(account_info)
            
            # 添加报告生成时间
            notify_content.append("")
            notify_content.append(f"📅 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
            
            # 发送通知
            send_notification(title, "\n".join(notify_content))
        else:
            logger.warning("无有效数据，跳过通知发送")
        
        # 计算任务耗时
        task_duration = datetime.now() - task_start
        logger.info(f"任务总耗时: {task_duration.total_seconds():.2f} 秒")
        
        # 返回退出码（0表示成功）
        return 0
    except Exception as e:
        logger.exception(f"任务执行失败: {str(e)}")
        # 发送错误通知
        error_title = "康师傅瓶盖统计任务失败"
        error_content = f"任务执行出错: {str(e)}\n\n请查看日志获取详细信息"
        send_notification(error_title, error_content)
        return 1

if __name__ == "__main__":
    import sys
    from datetime import datetime
    
    # 设置时区为北京时间
    os.environ['TZ'] = 'Asia/Shanghai'
    
    exit_code = main()
    sys.exit(exit_code)